/*
 * @Author: 姚潘涛
 * @Date: 2024-04-08 15:18:03
 * @LastEditors: 姚潘涛
 * @LastEditTime: 2024-10-10 17:19:58
 * @FilePath:
 * @Description:
 *
 * Copyright (c) 2024 by pandaman, All Rights Reserved.
 */
#include "xict_common/config/config.h"
#include "xict_common/log/log.h"
#include "xict_common/log/log_manager.h"
#include "xict_common/utils/yalk_helper.h"
#include "xict_cpp/core/pipeline/remote_controller.h"
#include "xict_cpp/utils/config.h"
#include "xict_driver/param/drivers_params.h"
#include "xict_driver/task/driver_manager.h"
#include <absl/flags/flag.h>
#include <absl/flags/parse.h>
#include <ecal/ecal.h>
#include <opencv2/core/utils/logger.hpp>

ABSL_FLAG(std::string, config_file, "", "Path to config file");
ABSL_FLAG(bool, verbose, false, "Enable verbose logging");
ABSL_FLAG(std::string, license_file, "", "Path to license file.");

void StartUI(const std::string& config_path, const std::string& app_path) {
    std::string cmd = fmt::format("{} --config_file {}", app_path, config_path);
    int ret         = system(cmd.c_str());
    if (ret != 0) {
        AERROR_F("Start UI Command {} execution failed.", cmd.c_str());
    } else {
        AINFO_F("Start UI Command executed successfully.");
    }
}

void StartUnity(const xict_cpp::core::stage::ScriptsPath& param) {
    int ret_start = system(param.unity_end_script.c_str());
    if (ret_start != 0) {
        AERROR_F("Start Unity Command {} execution failed.",
                 param.unity_end_script.c_str());
    } else {
        ADEBUG_F("Start Unity Command executed successfully.");
    }

    int ret_end = system(param.unity_start_script.c_str());
    if (ret_end != 0) {
        AERROR_F("Start Unity Command {} execution failed.",
                 param.unity_start_script.c_str());
    } else {
        ADEBUG_F("Start Unity Command executed successfully.");
    }
}

void StartRtspServer(
    const xict_cpp::core::stage::StreamProcessorStageParams& param) {
    std::string cmd =
        fmt::format("{} {}", param.rtsp_server_exe, param.rtsp_server_config);
    int ret = system(cmd.c_str());
    if (ret != 0) {
        AERROR_F("Start RTSP Server Command {} execution failed.", cmd.c_str());
    } else {
        AINFO_F("Start RTSP Server Command executed successfully.");
    }
}

int main(int argc, char* argv[]) {
    // 设置 OpenCV 的日志级别为 SILENT，禁用所有输出
    cv::utils::logging::setLogLevel(cv::utils::logging::LOG_LEVEL_ERROR);

    /// 参数解析
    absl::ParseCommandLine(argc, argv);
    std::string config_path  = absl::GetFlag(FLAGS_config_file);
    bool verbose             = absl::GetFlag(FLAGS_verbose);
    std::string license_file = absl::GetFlag(FLAGS_license_file);

    // check license
    ACHECK_F(xict_common::utils::ValidateLicense(license_file),
             "Invalid license.");

    /// 初始化eCAL
    eCAL::Initialize(argc, argv, "remote_control_pipeline");
    eCAL::Util::EnableLoopback(true);
    eCAL::Process::SetState(proc_sev_healthy, proc_sev_level1, "I feel good !");

    /// 初始化log
    std::string log_root_path =
        std::string(getenv("HOME")) + std::string("/.xict/logs");
    xict_common::log::LogManager::GetInstance()->Init(log_root_path);

    loguru::init(argc, argv);
    loguru::set_verbosity_to_name_callback(
        xict_common::log::custom_verbosity_to_name);
    loguru::set_name_to_verbosity_callback(
        xict_common::log::custom_name_to_verbosity);
    if (verbose) {
        loguru::g_stderr_verbosity = loguru::Verbosity_2;
    }

    /// 设置日志格式
    std::string log_path =
        xict_common::log::LogManager::GetInstance()->GetLogPath() +
        "/pipeline.log";
    loguru::add_file(log_path.c_str(), loguru::Append, loguru::Verbosity_MAX);

    /// 加载驱动程序参数
    std::shared_ptr<xict_driver::param::DriversParams> driver_params =
        std::make_shared<xict_driver::param::DriversParams>();
    driver_params->Load(config_path);

    /// 初始化driver manager
    std::shared_ptr<xict_driver::task::DriverManager> driver_manager =
        std::make_shared<xict_driver::task::DriverManager>();
    driver_manager->Initialize(driver_params);

    /// 读取配置文件
    xict_cpp::core::pipeline::RemoteControllerPipelineParams params;
    YAML::Node config = YAML::LoadFile(config_path);
    ACHECK_F(xict_cpp::utils::LoadConfig(config, "topic"),
             "Failed to load config file: {}", config_path);
    ACHECK_F(
        xict_cpp::utils::UpdateRemoteControllerPipelineParams(config, params),
        "Fail to update pipeline params with config: {}", config_path);

    // 开启rtsp服务端
    if (params.stream.rtsp_enable) {
        std::thread rtsp_thread(StartRtspServer, params.stream);
        rtsp_thread.detach();
    }

    /// 初始化pipeline
    xict_cpp::core::pipeline::RemoteControllerPipeline pipeline;
    if (!pipeline.Init(params)) {
        AERROR_F("Failed to init pipeline");
        return 1;
    }
    pipeline.Start();

    // 启动界面
    if(params.switcher.enable_ui_thread){
        std::thread ui_thread(StartUI, config_path,
                            params.scripts_path.ui_app_path);
        ui_thread.detach();
    }

    // 绘制车道线
    if(params.switcher.enable_unity_thread){
        std::thread drawline_thread(StartUnity, params.scripts_path);
        drawline_thread.detach();
    }

    // 启动所有驱动任务
    driver_manager->StartAllTasks();

    while (true) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }

    driver_manager->StopAllTasks();
    /// 释放资源
    eCAL::Finalize();

    return 0;
}